#pragma once
#include "ASN1Sequence.h"
#include "Name.h"
#include "ASN1UTCTime.h"
#include "ASN1ObjectIdentifier.h"
#include "TBSCertificateGenerator.h"
#include "ASN1ObjectIdentifier.h"
#include "ASN1Encoded.h"
#include "ASN1BitString.h"

namespace AppliedCryptography
{
	// Forward declare
	class TBSCertificateGenerator;

	class CertificateGenerator : public ASN1Sequence
	{
	private:
		TBSCertificateGenerator* _tbsGen;
		ASN1ObjectIdentifier* _sigAlgOid;
		ASN1BitString* _signature;

	public:
		//CertificateGenerator();
		CertificateGenerator(
			TBSCertificateGenerator* tbsGen = new TBSCertificateGenerator(), 
			ASN1ObjectIdentifier* sigAlgOID = new ASN1ObjectIdentifier(),
			ASN1BitString* signature = new ASN1BitString());
		virtual ~CertificateGenerator();

	private:
		virtual ASN1Sequence& add(ASN1Encodable& obj);
		virtual ASN1Encodable& get(unsigned int index) const;

	public:
		virtual unsigned int size() const;
		virtual std::vector<byte> getContentBits() const;

	public:
		virtual CertificateGenerator& setSerialNumber(unsigned long serialNumber);
		virtual CertificateGenerator& setIssuer(Name& issuer);
		virtual CertificateGenerator& setNotBefore(ASN1UTCTime& startTime);
		virtual CertificateGenerator& setNotAfter(ASN1UTCTime& endTime);
		virtual CertificateGenerator& setSubject(Name& subject);
		virtual CertificateGenerator& setPublicKey(ASN1Encoded& key);
		virtual CertificateGenerator& setSignatureAlgorithm(ASN1ObjectIdentifier& algOID);
		virtual CertificateGenerator& setExtensions(Extensions& extensions);
		virtual CertificateGenerator& generateSignature(ASN1Encoded& privateKey);
	};
}; // namespace AppliedCryptography
